package com.lemon.core.common.lang.util;

import java.io.*;
import java.util.*;

/**
 * @author lemon
 * @ClassName PropertiesUtils
 * @desc
 * @Date 2018/12/19 12:59
 * @Version 1.0
 **/
public class PropertiesUtils {

    private static Properties properties;

    private static PropertiesUtils propertiesUtils;


    /**
     *
     * @param resourcesPaths
     * @return
     */
    public static PropertiesUtils getInstance(String... resourcesPaths) {
        if (propertiesUtils == null) {
            synchronized (PropertiesUtils.class) {
                if (propertiesUtils == null) {
                    propertiesUtils = new PropertiesUtils(resourcesPaths);
                }
            }
        }
        return propertiesUtils;
    }

	public static PropertiesUtils getInstanceFromData(String data) {
		if (propertiesUtils == null) {
			synchronized (PropertiesUtils.class) {
				if (propertiesUtils == null) {
					propertiesUtils = new PropertiesUtils(data);
				}
			}
		}
		return propertiesUtils;
	}

    private PropertiesUtils(String... resourcesPaths) {
        properties = loadProperties(resourcesPaths);
    }

	private PropertiesUtils(String data) {
		properties = loadProperties(data);
	}

    public Properties getProperties() {
		return properties;
	}

	public List<String> getPrefixKeys(String prefixKey) {
		List<String> prefixKeys = new LinkedList<String>();
		for (String key : getAllKeys()) {
			if (key.contains(prefixKey)) {
				prefixKeys.add(key);
			}
		}
		return prefixKeys;
	}

	public List<String> getAllKeys() {
		List<String> keys = new LinkedList<String>();
		if (properties == null) {
			return keys;
		}

		for (Object key : properties.keySet()) {
			keys.add(key.toString());
		}
		return keys;
	}

	/**
	 * 取出String类型的Property，但以System的Property优先,如果都为Null则抛出异常.
	 */
	public String getString(String key) {
		String value = getValue(key);
		if (StringUtils.isBlank(value)) {
			return null;
		}
		return value;
	}

	/**
	 * 取出String类型的Property，但以System的Property优先.如果都为Null则返回Default值.
	 */
	public String getString(String key, String defaultValue) {
		String value = getValue(key);
		return StringUtils.isNotBlank(value) ? value : defaultValue;
	}

	/**
	 * 取出Integer类型的Property，但以System的Property优先.如果都为Null或内容错误则抛出异常.
	 */
	public Integer getInteger(String key) {
		String value = getValue(key);
		if (StringUtils.isBlank(value)) {
			return null;
		}
		return Integer.valueOf(value);
	}

	/**
	 * 取出Integer类型的Property，但以System的Property优先.如果都为Null则返回Default值，如果内容错误则抛出异常
	 */
	public Integer getInteger(String key, Integer defaultValue) {
		String value = getValue(key);
		return StringUtils.isNotBlank(value) ? Integer.valueOf(value) : defaultValue;
	}

	/**
	 * 取出Double类型的Property，但以System的Property优先.如果都为Null或内容错误则抛出异常.
	 */
	public Double getDouble(String key) {
		String value = getValue(key);
		if (StringUtils.isBlank(value)) {
			return null;
		}
		return Double.valueOf(value);
	}

	/**
	 * 取出Double类型的Property，但以System的Property优先.如果都为Null则返回Default值，如果内容错误则抛出异常
	 */
	public Double getDouble(String key, Integer defaultValue) {
		String value = getValue(key);
		return StringUtils.isNotBlank(value) ? Double.valueOf(value) : defaultValue;
	}

	/**
	 * 取出Boolean类型的Property，但以System的Property优先.如果都为Null抛出异常,如果内容不是true/
	 * false则返回false.
	 */
	public Boolean getBoolean(String key) {
		String value = getValue(key);
		if (StringUtils.isBlank(value)) {
			return null;
		}
		return Boolean.valueOf(value);
	}

	/**
	 * 取出Boolean类型的Property，但以System的Property优先.如果都为Null则返回Default值,如果内容不为true/
	 * false则返回false.
	 */
	public Boolean getBoolean(String key, boolean defaultValue) {
		String value = getValue(key);
		return StringUtils.isNotBlank(value) ? Boolean.valueOf(value) : defaultValue;
	}

	/**
	 * 取出Property，但以System的Property优先,取不到返回空字符串.
	 */
	private String getValue(String key) {
		String systemProperty = System.getProperty(key);
		if (systemProperty != null) {
			return systemProperty;
		}

		if (properties.containsKey(key)) {
			return properties.getProperty(key);
		}

		return "";
	}

	/**
	 * 载入多个文件, 文件路径使用Spring Resource格式.
	 */
	private Properties loadProperties(String... resourcesPaths) {
		Properties properties = new Properties();
        for (String resourcesPath : resourcesPaths) {
        	// 编译时环境
			InputStream inputStream = getClass().getClassLoader().getResourceAsStream(resourcesPath);
			try {
				if (inputStream != null) {
					properties.load(inputStream);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return properties;
	}

	private Properties loadProperties(String data) {
		Properties properties = new Properties();
		try {
			if (StringUtils.isNotBlank(data)) {
				properties.load(new StringReader(data));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return properties;
	}
}
